package xorm

import (
	"fmt"
	"gitee.com/stevenchin/gin_study/xorm/initxorm"
	"github.com/gin-gonic/gin"
	"net/http"
	"os"
)

/*
xorm提供了多种数据导出方式，支持多种文件格式的数据导出
*/

//一. 数据库结构和数据
// 1. Dump数据库结构和数据
func Dump(ctx *gin.Context) {

	param := ctx.Param("select")
	// DumpAll方法接收一个io.Writer接口来保存Dump出的数据库结构和数据的SQL语句，这个方法导出的SQL语句并不能通用。
	// 只针对当前engine所对应的数据库支持的SQL
	if param == "all" {
		ctx.Writer.Header().Add("Content-Disposition", fmt.Sprintf("attachment; filename=%s", "dump.txt"))
		ctx.Writer.Header().Add("Content-Type", "application/octet-stream")
		_ = initxorm.Engine.DumpAll(ctx.Writer)
	}
	// 保存文件到指定位置
	if param == "file" {
		_ = initxorm.Engine.DumpAllToFile("./dumpFile.txt")
		ctx.String(http.StatusOK, "保存数据库结构和数据到指定位置成功")
	}
}

// 2. Import 执行数据库SQL脚本
func Import(ctx *gin.Context) {

	if file, errs := ctx.FormFile("file"); errs != nil {
		ctx.String(http.StatusInternalServerError, "上传出错"+errs.Error())
		return
	} else {
		// 暂时保存在当前目录下
		if err := ctx.SaveUploadedFile(file, file.Filename); err != nil {
			ctx.String(http.StatusInternalServerError, "保存出错"+err.Error())
			return
		}
		// 删除文件
		defer func(name string) {
			err := os.Remove(name)
			if err != nil {

			}
		}(file.Filename)
		// engine.ImportFile(fpath string)导入
		if _, err := initxorm.Engine.ImportFile(file.Filename); err != nil {
			ctx.String(http.StatusInternalServerError, "执行出错："+err.Error())
			return
		}
		ctx.String(http.StatusOK, "通过文件导入成功")

		// engine.Import(r io.Reader)也可以。这里不做介绍了
	}
}

// 二. 查询结果集导出csv、tsv、xml、json、xlsx、yaml、html
// 	   TIPS：当某列值有可能为null的时候，需要使用各数据库类似IFNULL函数查询取值。由于查询出来的结果集是[]map[string]interface类型，
// 	   NULL字段将不会在map中保有key
func ExportFile(ctx *gin.Context) {

	param := ctx.Param("select")

	// 1. 导出CSV文件，filename为完整路径，headers为每列的列名，需要结果集中有该字段，此处[]string是为了确定列的顺序，perm为文件权限位
	strings := []string{"主键", "年龄", "名字", "创建时间"}
	sql := "select id as 主键, name as 名字, age as 年龄, FROM_UNIXTIME(create_time,'%Y-%m-%d %H:%i:%s') as 创建时间 from basic"
	if param == "csv" {
		fileName := "test.csv"
		_ = initxorm.Engine.SQL(sql).Query().SaveAsCSV(fileName, strings, os.ModePerm)
	}

	// 2. 导出TSV文件，filename为完整路径，headers为每列的列名，需要结果集中有该字段，此处[]string是为了确定列的顺序，perm为文件权限位
	if param == "tsv" {
		fileName := "test.tsv"
		_ = initxorm.Engine.SQL(sql).Query().SaveAsTSV(fileName, strings, os.ModePerm)
	}

	// 3. 导出HTML文件，filename为完整路径，headers为每列的列名，需要结果集中有该字段，此处[]string是为了确定列的顺序，perm为文件权限位
	if param == "html" {
		fileName := "test.html"
		_ = initxorm.Engine.SQL(sql).Query().SaveAsHTML(fileName, strings, os.ModePerm)
	}

	// 4. 导出XML文件，filename为完整路径，headers为每列的列名，需要结果集中有该字段，此处[]string是为了确定列的顺序，
	// perm为文件权限位
	if param == "xml" {
		fileName := "test.xml"
		_ = initxorm.Engine.SQL(sql).Query().SaveAsXML(fileName, strings, os.ModePerm)
	}

	// 5. 导出指定格式化的XML文件，filename为完整路径，headers为每列的列名，需要结果集中有该字段，此处[]string是为了确定
	// 列的顺序，perm为文件权限位

	// 6. 导出YAML文件，filename为完整路径，headers为每列的列名，需要结果集中有该字段，此处[]string是为了确定列的顺序，perm为文件权限位
	if param == "yaml" {
		fileName := "test.yaml"
		_ = initxorm.Engine.SQL(sql).Query().SaveAsYAML(fileName, strings, os.ModePerm)
	}

	// 7. 导出JSON文件，filename为完整路径，headers为每列的列名，需要结果集中有该字段，此处[]string是为了确定列的顺序，perm为文件权限位
	if param == "json" {
		fileName := "test.json"
		_ = initxorm.Engine.SQL(sql).Query().SaveAsJSON(fileName, strings, os.ModePerm)
	}

	// 8. 导出XLSX文件，filename为完整路径，headers为每列的列名，需要结果集中有该字段，此处[]string是为了确定列的顺序，perm为文件权限位
	if param == "xlsx" {
		fileName := "test.xlsx"
		_ = initxorm.Engine.SQL(sql).Query().SaveAsXLSX(fileName, strings, os.ModePerm)
	}
}

//三. 多Sheet页数据导出。如有需要可自行查阅：https://www.kancloud.cn/xormplus/xorm/170313
